package cn.hinglo.gameclaw.client.service;

import cn.hinglo.gameclaw.client.dao.GrabNoteDao;
import cn.hinglo.gameclaw.client.dao.LineUpDao;
import cn.hinglo.gameclaw.client.dao.UserInfoClientDao;
import cn.hinglo.gameclaw.data.entity.Result;
import cn.hinglo.gameclaw.data.utils.CommonUtils;
import cn.hinglo.gameclaw.data.utils.FieldUtils;
import cn.hinglo.gameclaw.data.utils.IdUtils;
import cn.hinglo.gameclaw.data.utils.ResultUtils;
import cn.hinglo.gameclaw.user.bean.Claw;
import cn.hinglo.gameclaw.user.bean.GrabNote;
import cn.hinglo.gameclaw.user.bean.LineUp;
import cn.hinglo.gameclaw.user.bean.UserInfo;
import cn.hutool.core.util.StrUtil;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

/**
 * @createTime: 2018/1/17
 * @author: HingLo
 * @description: 抓取记录的服务层
 */
@Service
@Slf4j
public class GrabNoteService {

    private final GrabNoteDao grabNoteDao;
    private final UserInfoClientDao userInfoClientDao;
    private final LineUpDao lineUpDao;

    @Autowired
    public GrabNoteService(GrabNoteDao grabNoteDao, UserInfoClientDao userInfoClientDao, LineUpDao lineUpDao) {
        this.grabNoteDao = grabNoteDao;
        this.userInfoClientDao = userInfoClientDao;
        this.lineUpDao = lineUpDao;
    }

    /**
     * 用户的抓取记录
     *
     * @param userId 用户的唯一Id
     * @return 抓取记录的结果
     */
    public Map<String, Object> listGrabNoteService(String userId, boolean status, int page, int pageSize) {
        GrabNote grabNote = new GrabNote().setUserId(userId).setStatus(status);
        //按照时间降序排序
        //如果是真就表示查询抓中但是没有消费的娃娃
        if (status) {
            grabNote.setOstatus(false);
        }
        //分页处理
        Page page1 = PageHelper.startPage(page, pageSize).setOrderBy("date desc");
        List<GrabNote> list = grabNoteDao.select(grabNote);
        //如果当前页面大于总页数，然后返回空
        if (page > page1.getPages()) {
            list.clear();
        }
        list.forEach(x -> {
            x.setHeader(CommonUtils.imgInstall(x.getHeader(), FieldUtils.IMAGE_3));
        });
        Map<String, Object> map = new HashMap<>(2);
        map.put("total", page1.getTotal());
        map.put("result", list);

        return map;
    }


    /**
     * 返货时候抓取的记录查询信息
     *
     * @param id     抓取记录Id数组
     * @param userId 用户的Id
     * @return 返回抓取记录集合
     */
    public List<GrabNote> orderGrabNoteService(String id[], String userId) {
        GrabNote grabNote = new GrabNote().setUserId(userId).setStatus(true).setOstatus(false);
        List<GrabNote> list = grabNoteDao.select(grabNote);
        List<GrabNote> res = new ArrayList<>();
        list.forEach(x -> {
            if (StrUtil.containsAny(x.getId(), id)) {
                res.add(x);
            }
        });
        return res;
    }


    /**
     * 入队申请
     *
     * @param cid 娃娃机编号
     * @return 返回入队申请结果
     */
    @Transactional(rollbackFor = RuntimeException.class)
    public Result resultService(int cid, Boolean status) {
        GrabNote grabNote = new GrabNote().setStatus(status);
        //定位抓取人
        LineUp lineUp = new LineUp().setCid(cid);
        List<LineUp> lineUps = lineUpDao.select(lineUp);
        if (lineUps.isEmpty()) {
            return ResultUtils.error("娃娃机的信息不正确，请重试");
        }
        // 取出最后一个，有时候如果没有通知到，那么这个记录一直存在
        lineUp = lineUps.get(lineUps.size() - 1);
        grabNote.setId(lineUp.getGid());

        if (!status) {
            grabNote.setScore(1);
        } else {
            grabNote.setScore(0);
        }
        System.out.println(grabNote);
        try {
            //更新抓取记录
            grabNoteDao.updateByPrimaryKeySelective(grabNote);
            // 删除排队记录信息
            lineUpDao.deleteByPrimaryKey(lineUp.getId());
            // 如果没有抓中，就赠送积分，需要更新积分到信息中
            if (!status) {
                grabNoteDao.updateUserScore(grabNote.getScore(), lineUp.getUserId());
            }
            log.info("抓取结果：{}", status ? "成功" : "失败");
        } catch (Exception e) {
            log.info("通知结果处理异常,请查看日志信息,时间：{},抓取人{},抓取结果{},娃娃机编号{}", new Date(), grabNote.getUserId(), status, cid);
            throw new RuntimeException("抓取结果处理异常");
        }

        return ResultUtils.success();

    }

    /**
     * 抓取前的通知处理
     *
     * @param cid    娃娃机的Id
     * @param userId 用户Id
     * @return 返回结果
     */
    public Result lineUPService(int cid, String userId) {
        Claw claw = grabNoteDao.findByIdClawDao(cid);
        if (claw == null) {
            return ResultUtils.error("娃娃机的信息不正确，请重试");
        }
        String id = IdUtils.getId();
        GrabNote grabNote = new GrabNote().setDate(new Date()).setId(id);
        LineUp lineUp = new LineUp().setCid(cid).setDate(new Date()).setUserId(userId).setGid(id);
        int gold = claw.getGold();
        //设置抓取记录信息
        grabNote.setCname(claw.getName());
        grabNote.setHeader(claw.getHeader());
        grabNote.setUserId(userId);
        grabNote.setGold(gold);
        grabNote.setStatus(false);
        grabNote.setCid(cid);
        // 获取用户信息
        UserInfo userInfo = userInfoClientDao.selectByPrimaryKey(userId);
        if (userInfo == null) {
            return ResultUtils.error("用户不存在");
        }
        //从用户的账号余额中扣除此次抓取所需要的金币
        if (userInfo.getGiveGold() >= gold) {
            userInfo.setGiveGold(userInfo.getGiveGold() - gold);
        } else if (userInfo.getGold() >= gold) {
            userInfo.setGold(userInfo.getGold() - gold);
        } else if (userInfo.getGiveGold() + userInfo.getGold() >= gold) {
            userInfo.setGold(userInfo.getGiveGold() - gold + userInfo.getGold());
            userInfo.setGiveGold(0);
        } else {
            return ResultUtils.error("金币数量不够,无法抓取");
        }
        if (lineUpDao.insert(lineUp) == 1 && grabNoteDao.insert(grabNote) > 0 && userInfoClientDao.updateByPrimaryKey(userInfo) == 1) {
            return ResultUtils.success(userInfo.getGiveGold() + userInfo.getGold());
        } else {
            throw new RuntimeException("金币扣除失败");
        }
    }

    public Map<String, Object> checkService(int cid, String userId) {
        Claw claw = grabNoteDao.findByIdClawDao(cid);
        int gold = claw.getGold();
        // 获取用户信息
        UserInfo userInfo = userInfoClientDao.selectByPrimaryKey(userId);
        if (userInfo == null) {
            throw new RuntimeException("用户信息不正确");
        }
        //从用户的账号余额中扣除此次抓取所需要的金币
        Map<String, Object> map = new HashMap<>(2);
        int meGold = userInfo.getGiveGold() + userInfo.getGold();
        map.put("res", meGold >= gold);
        map.put("gold", meGold);
        return map;

    }
}
